/**********************************************************************
 * Project : WoWGuildRoster (http://www.codeplex.com/WowGuildRoster/)
 * Module  : DotNetWarcraft.WoWGuildRoster.Business.LoadArmoryRoster
 **********************************************************************
 * 
 * 
 * 
 **********************************************************************
 * License : All code is subject to licensing terms per the Microsoft
 *   Permissive License (Ms-PL) v1.1. For full license information,
 *   refer to the packaged license.txt file.
 **********************************************************************
 * Revision History:
 * -----------------
 * 2008-11-30 -- Cliff Simpkins: Added logic to increment the error
 *                 count when the ArmoryParser throws an unhandled error
 **********************************************************************
 */
using System;
using System.Collections.Generic;
using System.Text;

using DotNetWarcraft.WoWGuildRoster;

namespace DotNetWarcraft.WoWGuildRoster.Business {
  public class LoadArmoryRoster : LoadRoster {

    public override int Version_Major {
      get {
        return 0;
      }
    }
    public override int Version_Minor {
      get {
        return 2;
      }
    }
    public override int Version_Build {
      get {
        return 0;
      }
    }

    protected Kralizek.WoWArmoryParser.RegionEnum KralizekRegion {
      get {
        return KralizekArmoryParser.KralizekRegion(this.Region);
      }
    }

    public LoadArmoryRoster(int rosterID) : base(rosterID) {
    }
    public override void Execute() {
      bool _loadedChars = false;

      if (this.Roster == null || this.RosterID < 0) {
        (new Business.Exceptions.GuildRosterError(new ApplicationException("Execute() - No roster to execute against"), -1, -1, _namespace + ".LoadRoster.Execute()")).WriteExceptionToDB();
        return;
      }

      //Grab the Armory Data Entry
      Kralizek.WoWArmoryParser.Guild _armoryGuild;
      try {
        _armoryGuild = Kralizek.WoWArmoryParser.ArmoryParser.GetGuild(this.ServerName, this.GuildName, this.KralizekRegion);

        _armoryGuild.Realm = this.ServerName;
        _armoryGuild.Name = this.GuildName;
        _armoryGuild.Region = this.KralizekRegion;

        this.LoadEntry.Load_Source = "WoW Armory";
        this.LoadEntry.Load_StartedBy = "Scheduler";
        this.UpdateLoadEntry();

        GuildRosterController.ProtectLocalCache = true;

        foreach (Kralizek.WoWArmoryParser.GuildMember _armoryChar in _armoryGuild.Members) {
          GuildEntry _entry = new GuildEntry();
          try {
            _entry = KralizekArmoryParser.ProcessArmoryCharEntry(_armoryChar, this.ServerName, this.RosterID, this.LoadEntry.Load_ID);
            _entry.Char_Region_Enum = this.Region;
            _entry.Roster_ID = this.RosterID;
            _entry.Char_Guild = this.GuildName;

            _entry.Last_Update_Date = DateTime.UtcNow;
            _entry.Last_Load_Date = DateTime.UtcNow;
            _entry.Last_Load_ID = this.LoadEntry.Load_ID;
            _entry.Current_Flag = 1;

            if (_entry.Char_ID > 0) {
              GuildRosterController.UpdateCharEntry(_entry);
              this.Status_Updates++;
              _loadedChars = true;
            } else {
              _entry.LoadStatus_Enum = WGR_LoadStatus.NewOrEmpty;
              _entry.Char_ID = GuildRosterController.AddCharEntry(_entry);
              this.Status_Adds++;
              _loadedChars = true;
            }
            this.UpdateLoadEntry();

          } catch (Exception _e) {
            (new Business.Exceptions.GuildCharEntryError(_e, -1, this.RosterID, _entry.Char_ID, _namespace + ".LoadArmoryRoster.Execute() - Processing " + _armoryChar.Name + "(" + this.ServerName + ")")).WriteExceptionToDB();
            this.Status_Errors++;
            this.UpdateLoadEntry();
          }
        }
        if (_loadedChars) {
          GuildRosterController.ProcessEntries_MarkPriorUnprocessed(this.RosterID, this.LoadEntry.Load_ID);
        }
      } catch (Exception _e) {
        (new Business.Exceptions.GuildRosterError(_e, this.LoadEntry.Load_ID, this.RosterID, _namespace + ".LoadArmoryRoster.Execute(" + this.RosterID.ToString() + ") - Exception while calling Kralizek.WoWArmoryParser.ArmoryParser.GetGuild()")).WriteExceptionToDB();
        this.Status_Errors++;
        throw _e;
      } finally {
        GuildRosterController.ProtectLocalCache = false;
        GuildRosterController.ForceLocalCacheRefresh();
      }
    }
  }

  public class LoadArmoryCharEntry : LoadCharEntry {

    public override int Version_Major {
      get {
        return 0;
      }
    }
    public override int Version_Minor {
      get {
        return 2;
      }
    }
    public override int Version_Build {
      get {
        return 0;
      }
    }

    protected Kralizek.WoWArmoryParser.RegionEnum KralizekRegion {
      get {
        return KralizekArmoryParser.KralizekRegion(this.Region);
      }
    }

    public LoadArmoryCharEntry(int CharID)
      : base(CharID) {
    }
    public LoadArmoryCharEntry(int CharID, DataLoad existingDataLoad)
      : base(CharID, existingDataLoad) {
    }
    public override void Execute() {

      this.LoadEntry.Load_Source = "WoW Armory";
      this.LoadEntry.Load_StartedBy = "Scheduler";

      if (this.Entry == null || this.CharID < 0) {
        (new Business.Exceptions.GuildRosterError(new ApplicationException("Execute() - No chat entry to execute against"), -1, -1, _namespace + ".LoadCharEntry.Execute()")).WriteExceptionToDB();
        return;
      }

      //Grab the Armory Data Entry
      Kralizek.WoWArmoryParser.Character _armoryCharInfo;

      try {
        _armoryCharInfo = Kralizek.WoWArmoryParser.ArmoryParser.GetCharacter(Entry.Char_Server, Entry.Char_Name, this.KralizekRegion);

        if (_armoryCharInfo.Name == null || _armoryCharInfo.Name == "") {
          this.LoadEntry.LastCharIdLoaded = Entry.Char_ID;
          this.Status_Errors++;
          this.UpdateLoadEntry();
        } else {
          GuildEntry _entry = new GuildEntry();
          try {
            bool _updated = false;
            _entry = KralizekArmoryParser.ProcessArmoryCharEntry(_armoryCharInfo, this.ServerName, this.RosterID, this.LoadEntry.Load_ID, ref _updated);
            _entry.Char_Region_Enum = this.Region;
            if (_entry.Roster_ID < 0) {
              _entry.Roster_ID = this.RosterID;
            }

            _entry.Last_Update_Date = DateTime.UtcNow;
            _entry.Last_Load_Date = DateTime.UtcNow;
            _entry.Last_Load_ID = this.LoadEntry.Load_ID;
            _entry.Current_Flag = 1;


            this.LoadEntry.LastCharIdLoaded = _entry.Char_ID;
            if (_entry.Char_ID > 0) {
              GuildRosterController.UpdateCharEntry(_entry);
              if (_updated) {
                this.Status_Updates++;
              } else { this.Status_Skips++; }
            } else if (_entry.Char_Name == null || _entry.Char_Name == "") {
              _entry.LoadStatus_Enum = WGR_LoadStatus.NewOrEmpty;
              _entry.Char_ID = GuildRosterController.AddCharEntry(_entry);
              this.Status_Adds++;
            }
            this.UpdateLoadEntry();

          } catch (Exception _e) {
            (new Business.Exceptions.GuildCharEntryError(_e, -1, this.RosterID, _entry.Char_ID, _namespace + ".LoadArmoryCharEntry.Execute(" + this.CharID.ToString() + ") - Processing " + _armoryCharInfo.Name + "(" + this.ServerName + ")")).WriteExceptionToDB();
            this.LoadEntry.LastCharIdLoaded = _entry.Char_ID;
            this.Status_Errors++;
            this.UpdateLoadEntry();
          }
        }
      } catch (Exception _e) {
        (new Business.Exceptions.GuildRosterError(_e, this.LoadEntry.Load_ID, this.RosterID, _namespace + ".LoadArmoryCharEntry.Execute(" + this.CharID.ToString() + ") - Exception while calling Kralizek.WoWArmoryParser.ArmoryParser.GetCharacter()")).WriteExceptionToDB();
        this.Status_Errors++;
        this.UpdateLoadEntry();
        throw _e;
      } finally {
      }
    }
  }

  public class KralizekArmoryParser {
    private static String _namespace = "DotNetWarcraft.WoWGuildRoster.Business";
    private static String _className = _namespace + ".KralizekArmoryParser";

    #region Public Kralizek Translation Methods
    public static Kralizek.WoWArmoryParser.RegionEnum KralizekRegion(Business.WarcraftRegions wgrRegion) {
      switch (wgrRegion) {
        case Business.WarcraftRegions.RegionEurope:
          return Kralizek.WoWArmoryParser.RegionEnum.Europe;
        case Business.WarcraftRegions.RegionUS:
          return Kralizek.WoWArmoryParser.RegionEnum.USA;
        default:
          return Kralizek.WoWArmoryParser.RegionEnum.USA;
      }
    }

    public static GuildEntry ProcessArmoryCharEntry(Kralizek.WoWArmoryParser.GuildMember armoryGuildMember, String serverName, int rosterID, int loadID) {
      GuildEntry _entry = new GuildEntry();

      _entry = GuildRosterController.GetCharEntry_DB(armoryGuildMember.Name, serverName);

      _entry.Char_Name = armoryGuildMember.Name;
      _entry.Char_Server = serverName;
      _entry.Game_Guild_Rank = armoryGuildMember.Rank;

      _entry.Char_Gender = armoryGuildMember.Gender.ToString();
      _entry.Char_Race = armoryGuildMember.Race.ToString();
      _entry.Char_Class = armoryGuildMember.CharClass.ToString();
      _entry.Char_Level = armoryGuildMember.Level;

      return _entry;
    }

    public static GuildEntry ProcessArmoryCharEntry(Kralizek.WoWArmoryParser.Character armoryCharInfo, String serverName, int rosterID, int loadID, ref bool updated) {
      GuildEntry _entry = new GuildEntry();
      int _rosterID = -1;
      updated = false;

      _entry = WoWGuildRoster.Business.GuildRosterController.GetCharEntry_DB(armoryCharInfo.Name, serverName);

      if (_entry == null) {
        _entry = new GuildEntry();
        _rosterID = -1;
      } else {
        _rosterID = _entry.Roster_ID;
      }

      if (armoryCharInfo.IsValid && (_entry.NeedsToBeUpdated || _entry.Game_Last_Login < armoryCharInfo.LastUpdate)) {

        //Load up the basic information
        _entry.Char_Name = armoryCharInfo.Name.ToString();
        _entry.Char_Server = armoryCharInfo.Realm;
        _entry.Char_Guild = armoryCharInfo.GuildName;

        _entry.Char_Gender = armoryCharInfo.Gender.ToString();
        _entry.Char_Race = armoryCharInfo.Race.ToString();
        _entry.Char_Class = armoryCharInfo.CharClass.ToString();
        _entry.Char_Level = armoryCharInfo.Level;
        _entry.Game_Last_Login = armoryCharInfo.LastUpdate;

        ProcessArmoryCharEntry_Profs(ref armoryCharInfo, ref _entry, _rosterID, loadID);
        ProcessArmoryCharEntry_Specs(ref armoryCharInfo, ref _entry, _rosterID, loadID);
        ProcessArmoryCharEntry_Stats(ref armoryCharInfo, ref _entry, _rosterID, loadID);

        _entry.LoadStatus_Enum = WGR_LoadStatus.LoadedSuccessfully;
        updated = true;

      }

      return _entry;
    }


    #endregion
    #region Internal/Supporting Kralizek Translation Methods
    protected static void ProcessArmoryCharEntry_Profs(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, ref GuildEntry charEntry, int rosterID, int loadID) {
      //Load up the profession information
      if (armoryCharInfo.Skills != null) {
        //Extract the professions information
        if (armoryCharInfo.Skills.Professions != null) {
          if (armoryCharInfo.Skills.Professions.Count >= 1 && armoryCharInfo.Skills.Professions[0] != null) {
            charEntry.Char_Prof1 = armoryCharInfo.Skills.Professions[0].Name.ToString();
            charEntry.Char_Prof1_Level = armoryCharInfo.Skills.Professions[0].Value;
          }

          if (armoryCharInfo.Skills.Professions.Count >= 2 && armoryCharInfo.Skills.Professions[1] != null) {
            charEntry.Char_Prof2 = armoryCharInfo.Skills.Professions[1].Name.ToString();
            charEntry.Char_Prof2_Level = armoryCharInfo.Skills.Professions[1].Value;
          }
        }

      }

    }
    protected static void ProcessArmoryCharEntry_Specs(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, ref GuildEntry charEntry, int rosterID, int loadID) {
      //Load up the spec information
      if (armoryCharInfo.TalentSpec1 != null) {
        charEntry.AssignSpec(armoryCharInfo.TalentSpec1.PrimaryTree, armoryCharInfo.TalentSpec1.TreeOne, armoryCharInfo.TalentSpec1.TreeTwo, armoryCharInfo.TalentSpec1.TreeThree, armoryCharInfo.TalentSpec1.TalentGroup);
      }

      if (armoryCharInfo.TalentSpec2 != null) {
        charEntry.AssignSpec(armoryCharInfo.TalentSpec2.PrimaryTree, armoryCharInfo.TalentSpec2.TreeOne, armoryCharInfo.TalentSpec2.TreeTwo, armoryCharInfo.TalentSpec2.TreeThree, armoryCharInfo.TalentSpec2.TalentGroup);
      }

      if (armoryCharInfo.TalentSpec1.ActiveTalent == 1) {
        charEntry.Char_Spec_Active = 1;
      } else if (armoryCharInfo.TalentSpec2.ActiveTalent == 1) {
        charEntry.Char_Spec_Active = 2;
      }
    }
    protected static void ProcessArmoryCharEntry_Stats(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, ref GuildEntry charEntry, int rosterID, int loadID) {
      List<GuildEntryStat> _charStats = new List<GuildEntryStat>();

      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Bars(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);

      if (armoryCharInfo.Reputations != null) {
        KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Reps(armoryCharInfo.GroupedReputations, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      }

      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Base(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Defense(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Melee(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Ranged(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Spell(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Resists(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Armor(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Profs(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_SecSkills(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);
      KralizekArmoryParser.ProcessArmoryCharEntry_Stats_Weapons(ref armoryCharInfo, charEntry.Char_ID, rosterID, loadID, ref _charStats);

      // Arena PvP Processing
      if (armoryCharInfo.Team2v2 != null && armoryCharInfo.Team2v2.Name != null && armoryCharInfo.Team2v2.Name != "") {
        KralizekArmoryParser.ProcessArmoryCharEntry_Stats_ArenaTeams(armoryCharInfo.Team2v2, charEntry.Char_ID, charEntry.Char_Name, rosterID, loadID, ref _charStats);
        }
      if (armoryCharInfo.Team3v3 != null && armoryCharInfo.Team3v3.Name != null && armoryCharInfo.Team3v3.Name != "") {
        KralizekArmoryParser.ProcessArmoryCharEntry_Stats_ArenaTeams(armoryCharInfo.Team3v3, charEntry.Char_ID, charEntry.Char_Name, rosterID, loadID, ref _charStats);
        }
      if (armoryCharInfo.Team5v5 != null && armoryCharInfo.Team5v5.Name != null && armoryCharInfo.Team5v5.Name != "") {
        KralizekArmoryParser.ProcessArmoryCharEntry_Stats_ArenaTeams(armoryCharInfo.Team5v5, charEntry.Char_ID, charEntry.Char_Name, rosterID, loadID, ref _charStats);
        }

      //Clear out the existing skills that may end up orphaned
      GuildRosterController.DeleteCharEntryStats_ByCharEntry(charEntry.Char_ID, WarcraftStatTypes.ArenaTeamInfo);
      GuildRosterController.DeleteCharEntryStats_ByCharEntry(charEntry.Char_ID, WarcraftStatTypes.ProfessionSkill);
      GuildRosterController.DeleteCharEntryStats_ByCharEntry(charEntry.Char_ID, WarcraftStatTypes.SecondarySkill);

      foreach (GuildEntryStat _stat in _charStats) {
        GuildRosterController.AddCharEntryStat(_stat);
      }
    }

    protected static void ProcessArmoryCharEntry_Stats_Bars(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      _charStats.Add(new GuildEntryStat(entryID, WGRConstants.WowStatType_Int(WarcraftStatTypes.BaseCharStats), "Base Stats", "HealthBarTotal", armoryCharInfo.HealthBar.Total, armoryCharInfo.HealthBar.ToTypeString()));
      _charStats.Add(new GuildEntryStat(entryID, WGRConstants.WowStatType_Int(WarcraftStatTypes.BaseCharStats), "Base Stats", "SecondBarTotal", armoryCharInfo.SecondBar.Total, armoryCharInfo.SecondBar.ToTypeString()));
    }
    protected static void ProcessArmoryCharEntry_Stats_Base(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.BaseStats != null) {
        int _statAbility = WGRConstants.WowStatType_Int(WarcraftStatTypes.Ability);

        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Agility", armoryCharInfo.BaseStats.Agility));
        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Armor", armoryCharInfo.BaseStats.Armor));
        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Intellect", armoryCharInfo.BaseStats.Intellect));
        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Spirit", armoryCharInfo.BaseStats.Spirit));
        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Stamina", armoryCharInfo.BaseStats.Stamina));
        _charStats.Add(new GuildEntryStat(entryID, _statAbility, "Base Stats", "Strength", armoryCharInfo.BaseStats.Strength));
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Defense(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Defense != null) {
        int _statDefense = WGRConstants.WowStatType_Int(WarcraftStatTypes.DefenseSkill);

        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Armor", "Base", armoryCharInfo.Defense.Armor.Base));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Armor", "DamageReductionPercent", armoryCharInfo.Defense.Armor.DamageReductionPercent));
        //_charStats.Add(new GuildEntryStat(entryID, _statDefense, "Armor", "Effective", armoryCharInfo.Defense.Armor.Effective));
        //_charStats.Add(new GuildEntryStat(entryID, _statDefense, "Block", "IncreasedByRating", armoryCharInfo.Defense.Block.IncreasedByRating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Block", "Percent", armoryCharInfo.Defense.Block.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Block", "Rating", armoryCharInfo.Defense.Block.Rating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Defense", "Rating", armoryCharInfo.Defense.Defense.Rating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Defense", "Value", armoryCharInfo.Defense.Defense.Value));
        //_charStats.Add(new GuildEntryStat(entryID, _statDefense, "Dodge", "IncreasedByRating", armoryCharInfo.Defense.Dodge.IncreasedByRating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Dodge", "Percent", armoryCharInfo.Defense.Dodge.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Dodge", "Rating", armoryCharInfo.Defense.Dodge.Rating));
        //_charStats.Add(new GuildEntryStat(entryID, _statDefense, "Parry", "IncreasedByRating", armoryCharInfo.Defense.Parry.IncreasedByRating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Parry", "Percent", armoryCharInfo.Defense.Parry.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Parry", "Rating", armoryCharInfo.Defense.Parry.Rating));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Resilience", "DamageReduction", armoryCharInfo.Defense.Resilience.DamageReduction));
        //_charStats.Add(new GuildEntryStat(entryID, _statDefense, "Resilience", "HitReduction", armoryCharInfo.Defense.Resilience.HitReduction));
        _charStats.Add(new GuildEntryStat(entryID, _statDefense, "Resilience", "Rating", armoryCharInfo.Defense.Resilience.Rating));
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Melee(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Melee != null) {
        int _statMelee = WGRConstants.WowStatType_Int(WarcraftStatTypes.MeleeSkill);

        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "AttackPower", "Base", armoryCharInfo.Melee.AttackPower.Base));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "AttackPower", "Effective", armoryCharInfo.Melee.AttackPower.Effective));
        //_charStats.Add(new GuildEntryStat(entryID, _statMelee, "AttackPower", "IncreasedDPS", armoryCharInfo.Melee.AttackPower.IncreasedDPS));
        //_charStats.Add(new GuildEntryStat(entryID, _statMelee, "CritChance", "IncreasedByRating", armoryCharInfo.Melee.CritChance.IncreasedByRating));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "CritChance", "Percent", armoryCharInfo.Melee.CritChance.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "CritChance", "Rating", armoryCharInfo.Melee.CritChance.Rating));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "Expertise", "Value", armoryCharInfo.Melee.Expertise.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "Expertise", "Percent", armoryCharInfo.Melee.Expertise.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "HitRating", "IncreasedHitChance", armoryCharInfo.Melee.HitRating.IncreasedHitChance));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "HitRating", "Penetration", armoryCharInfo.Melee.HitRating.Penetration));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "HitRating", "Value", armoryCharInfo.Melee.HitRating.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "MainHand", "Damage", armoryCharInfo.Melee.MainHand.Damage.DPS));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "MainHand", "Skill", armoryCharInfo.Melee.MainHand.Skill.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "MainHand", "HasteRating", armoryCharInfo.Melee.MainHand.Speed.HasteRating));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "OffHand", "Damage", armoryCharInfo.Melee.OffHand.Damage.DPS));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "OffHand", "Skill", armoryCharInfo.Melee.OffHand.Skill.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statMelee, "OffHand", "HasteRating", armoryCharInfo.Melee.OffHand.Speed.HasteRating));
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Ranged(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Ranged != null) {
        int _statRanged = WGRConstants.WowStatType_Int(WarcraftStatTypes.RangedSkill);

        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "AttackPower", "Base", armoryCharInfo.Ranged.AttackPower.Base));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "AttackPower", "Effective", armoryCharInfo.Ranged.AttackPower.Effective));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "AttackPower", "IncreasedDPS", armoryCharInfo.Ranged.AttackPower.IncreasedDPS));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "CritChance", "IncreasedByRating", armoryCharInfo.Ranged.CritChance.IncreasedByRating));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "CritChance", "Percent", armoryCharInfo.Ranged.CritChance.Percent));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "CritChance", "Rating", armoryCharInfo.Ranged.CritChance.Rating));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "HitRating", "IncreasedHitChance", armoryCharInfo.Ranged.HitRating.IncreasedHitChance));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "HitRating", "Penetration", armoryCharInfo.Ranged.HitRating.Penetration));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "HitRating", "Value", armoryCharInfo.Ranged.HitRating.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "Weapon", "Damage", armoryCharInfo.Ranged.Weapon.Damage.DPS));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "Weapon", "Skill", armoryCharInfo.Ranged.Weapon.Skill.Value));
        //_charStats.Add(new GuildEntryStat(entryID, _statRanged, "Weapon", "Speed", armoryCharInfo.Ranged.Weapon.Speed.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statRanged, "Weapon", "HasteRating", armoryCharInfo.Ranged.Weapon.Speed.HasteRating));
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Spell(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Spell != null) {
        int _statSpell = WGRConstants.WowStatType_Int(WarcraftStatTypes.SpellSkill);

        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Arcane", "CritChance", armoryCharInfo.Spell.Arcane.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Arcane", "DamageBonus", armoryCharInfo.Spell.Arcane.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "CritRating", "CritRating", armoryCharInfo.Spell.CritRating));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "HasteRating", "HasteRating", armoryCharInfo.Spell.HasteRating.HasteRating));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Fire", "CritChance", armoryCharInfo.Spell.Fire.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Fire", "DamageBonus", armoryCharInfo.Spell.Fire.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Frost", "CritChance", armoryCharInfo.Spell.Frost.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Frost", "DamageBonus", armoryCharInfo.Spell.Frost.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "HealingBonus", "HealingBonus", armoryCharInfo.Spell.HealingBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "HitRating", "IncreasedHitChance", armoryCharInfo.Spell.HitRating.IncreasedHitChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "HitRating", "Value", armoryCharInfo.Spell.HitRating.Value));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Holy", "CritChance", armoryCharInfo.Spell.Holy.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Holy", "DamageBonus", armoryCharInfo.Spell.Holy.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "ManaRegen", "WhileCasting", armoryCharInfo.Spell.ManaRegen.WhileCasting));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "ManaRegen", "WhileNotCasting", armoryCharInfo.Spell.ManaRegen.WhileNotCasting));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Nature", "CritChance", armoryCharInfo.Spell.Nature.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Nature", "DamageBonus", armoryCharInfo.Spell.Nature.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Shadow", "CritChance", armoryCharInfo.Spell.Shadow.CritChance));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "Shadow", "DamageBonus", armoryCharInfo.Spell.Shadow.DamageBonus));
        _charStats.Add(new GuildEntryStat(entryID, _statSpell, "SpellPenetration", "SpellPenetration", armoryCharInfo.Spell.SpellPenetration));
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Resists(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Resistances != null) {
        int _statResSkill = WGRConstants.WowStatType_Int(WarcraftStatTypes.Resistances);

        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Arcane", armoryCharInfo.Resistances.ArcaneRes));
        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Fire", armoryCharInfo.Resistances.FireRes));
        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Frost", armoryCharInfo.Resistances.FrostRes));
        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Holy", armoryCharInfo.Resistances.HolyRes));
        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Nature", armoryCharInfo.Resistances.NatureRes));
        _charStats.Add(new GuildEntryStat(entryID, _statResSkill, "Resistance", "Shadow", armoryCharInfo.Resistances.ShadowRes));

      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Armor(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Skills.ArmorProficiencies != null) {
        int _statArmSkill = WGRConstants.WowStatType_Int(WarcraftStatTypes.WeaponSkill);
        foreach (Kralizek.WoWArmoryParser.Skill _skill in armoryCharInfo.Skills.ArmorProficiencies) {
          _charStats.Add(new GuildEntryStat(entryID, _statArmSkill, "Armor Profs", _skill.Name, _skill.Value, _skill.Key));
        }
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Profs(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Skills.Professions != null) {
        int _statProfSkill = WGRConstants.WowStatType_Int(WarcraftStatTypes.ProfessionSkill);
        foreach (Kralizek.WoWArmoryParser.Skill _skill in armoryCharInfo.Skills.Professions) {
          _charStats.Add(new GuildEntryStat(entryID, _statProfSkill, "Profession", _skill.Name, _skill.Value, _skill.Key));
        }
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_SecSkills(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {

      if (armoryCharInfo.Skills.SecondarySkills != null) {
        int _statSecSkill = WGRConstants.WowStatType_Int(WarcraftStatTypes.SecondarySkill);
        foreach (Kralizek.WoWArmoryParser.Skill _skill in armoryCharInfo.Skills.SecondarySkills) {
          _charStats.Add(new GuildEntryStat(entryID, _statSecSkill, "Secondary Skills", _skill.Name, _skill.Value, _skill.Key));
        }
      }
    }
    protected static void ProcessArmoryCharEntry_Stats_Weapons(ref Kralizek.WoWArmoryParser.Character armoryCharInfo, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {
      if (armoryCharInfo.Skills.WeaponsSkills != null) {
        int _statWepSkill = WGRConstants.WowStatType_Int(WarcraftStatTypes.WeaponSkill);
        foreach (Kralizek.WoWArmoryParser.Skill _skill in armoryCharInfo.Skills.WeaponsSkills) {
          _charStats.Add(new GuildEntryStat(entryID, _statWepSkill, "Weapon Skills", _skill.Name, _skill.Value, _skill.Key));
        }
      }
    }

    protected static void ProcessArmoryCharEntry_Stats_Reps(Kralizek.WoWArmoryParser.Reputations armoryReps, int entryID, int rosterID, int loadID, ref List<GuildEntryStat> _charReps) {

      try {
        if (armoryReps != null) {
          foreach (Kralizek.WoWArmoryParser.GroupedReputationCollection _factionColl in armoryReps.FactionsCollection) {
            if (_factionColl != null) {
              foreach (KeyValuePair<String, Kralizek.WoWArmoryParser.Reputation> _armoryRep in _factionColl) {
                try {
                  GuildEntryStat _rep = new GuildEntryStat(entryID,
                    WGRConstants.WowStatType_Int(WarcraftStatTypes.Reputation),
                    _factionColl.Name, _armoryRep.Value.Name,
                    _armoryRep.Value.Value, _armoryRep.Value.Status.ToString());

                  _charReps.Add(_rep);
                } catch (Exception e) {
                  (new Business.Exceptions.GuildCharEntryStatError(e, loadID, rosterID, entryID, -1, _className + ".ProcessArmoryReputations - Exception while parsing reputation")).WriteExceptionToDB();
                }
              }
            }
          }
        }

      } catch (Exception e) {
        (new Business.Exceptions.GuildCharEntryError(e, loadID, rosterID, entryID, _className + "ProcessArmoryCharEntry_Stats_Reps()")).WriteExceptionToDB();
      }
    }

    protected static void ProcessArmoryCharEntry_Stats_ArenaTeams(Kralizek.WoWArmoryParser.ArenaTeam arenaTeamInfo, int entryID, String entryName, int rosterID, int loadID, ref List<GuildEntryStat> _charStats) {

      try {
        if (arenaTeamInfo != null) {
          String _arenaType = "";
          switch (arenaTeamInfo.Size) {
            case Kralizek.WoWArmoryParser.ArenaTeamSizeEnum.Team2v2: _arenaType = "Team2v2"; break;
            case Kralizek.WoWArmoryParser.ArenaTeamSizeEnum.Team3v3: _arenaType = "Team3v3"; break;
            case Kralizek.WoWArmoryParser.ArenaTeamSizeEnum.Team5v5: _arenaType = "Team5v5"; break;
            default: _arenaType = "Unknown"; break;
            }

          int _statArenaTm = WGRConstants.WowStatType_Int(WarcraftStatTypes.ArenaTeamInfo);

          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "TeamName", -1, arenaTeamInfo.Name));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "TeamRanking", arenaTeamInfo.Ranking, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "TeamRating", arenaTeamInfo.Rating, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "GamesWeek", arenaTeamInfo.GamesInWeek.Played, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "WinsWeek", arenaTeamInfo.GamesInWeek.Wins, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "WinsGamesWeek", -1, arenaTeamInfo.GamesInWeek.Wins.ToString() + " / " + arenaTeamInfo.GamesInWeek.Played.ToString()));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "GamesSeason", arenaTeamInfo.GamesInSeason.Played, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "WinsSeason", arenaTeamInfo.GamesInSeason.Wins, ""));
          _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "WinsGamesSeason", -1, arenaTeamInfo.GamesInSeason.Wins.ToString() + " / " + arenaTeamInfo.GamesInSeason.Played.ToString()));

          if (arenaTeamInfo.Members != null) {
            foreach (Kralizek.WoWArmoryParser.ArenaMember _member in arenaTeamInfo.Members) {
              if (_member.Name == entryName) {
                _charStats.Add(new GuildEntryStat(entryID, _statArenaTm, _arenaType, "PersonalRating", _member.Rank, ""));
                }
              }
            }
          }

        } catch (Exception e) {
        (new Business.Exceptions.GuildCharEntryError(e, loadID, rosterID, entryID, "DotNetWarcraft.WoWGuildRoster.Business.LoadArmoryRoster.ProcessArenaTeamInfo")).WriteExceptionToDB();
        }
      }

    #endregion

  }
}
